package com.company.loganalyzer.service.impl;

import com.company.loganalyzer.service.LLMService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * DeepSeek LLM服务实现
 * 
 * 使用DeepSeek Coder模型进行意图分析和结果综合
 */
@Service
public class DeepSeekLLMService implements LLMService {
    
    private static final Logger logger = LoggerFactory.getLogger(DeepSeekLLMService.class);
    
    @Value("${deepseek.api-key:}")
    private String apiKey;
    
    @Value("${deepseek.api-url:https://api.deepseek.com/v1/chat/completions}")
    private String apiUrl;
    
    @Value("${deepseek.model:deepseek-coder}")
    private String model;
    
    @Value("${deepseek.enabled:false}")
    private boolean enabled;
    
    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;
    
    public DeepSeekLLMService() {
        this.restTemplate = new RestTemplate();
        this.objectMapper = new ObjectMapper();
    }
    
    @Override
    public ToolSelectionResult analyzeAndSelectTools(String query, List<String> availableTools) {
        if (!enabled || apiKey.isEmpty()) {
            // 返回基于规则的简单工具选择
            return performRuleBasedToolSelection(query, availableTools);
        }
        
        try {
            String prompt = buildToolSelectionPrompt(query, availableTools);
            String response = callDeepSeekAPI(prompt);
            return parseToolSelectionResponse(response, availableTools);
        } catch (Exception e) {
            logger.warn("LLM工具选择失败，使用基于规则的备选方案: {}", e.getMessage());
            return performRuleBasedToolSelection(query, availableTools);
        }
    }
    
    @Override
    public AnalysisResponse synthesizeResponse(String query, Map<String, Object> toolResults) {
        if (!enabled || apiKey.isEmpty()) {
            // 返回基于模板的简单响应
            return performTemplateBasedSynthesis(query, toolResults);
        }
        
        try {
            String prompt = buildSynthesisPrompt(query, toolResults);
            String response = callDeepSeekAPI(prompt);
            return parseSynthesisResponse(response);
        } catch (Exception e) {
            logger.warn("LLM结果综合失败，使用基于模板的备选方案: {}", e.getMessage());
            return performTemplateBasedSynthesis(query, toolResults);
        }
    }
    
    @Override
    public boolean isAvailable() {
        return enabled && !apiKey.isEmpty();
    }
    
    /**
     * 基于规则的工具选择（备选方案）
     */
    private ToolSelectionResult performRuleBasedToolSelection(String query, List<String> availableTools) {
        List<String> selectedTools = new ArrayList<>();
        Map<String, Object> parameters = new HashMap<>();
        
        String lowerQuery = query.toLowerCase();
        
        // 基于关键词的规则匹配
        if (lowerQuery.contains("搜索") || lowerQuery.contains("查找") || lowerQuery.contains("search")) {
            selectedTools.add("search_logs");
        }
        
        if (lowerQuery.contains("错误") || lowerQuery.contains("异常") || lowerQuery.contains("error") || lowerQuery.contains("exception")) {
            selectedTools.add("analyze_errors");
        }
        
        if (lowerQuery.contains("统计") || lowerQuery.contains("分析") || lowerQuery.contains("统计分析")) {
            selectedTools.add("get_log_statistics");
        }
        
        if (lowerQuery.contains("追踪") || lowerQuery.contains("trace") || lowerQuery.contains("链路")) {
            // 如果包含traceId相关关键词，优先使用智能分析
            if (lowerQuery.contains("traceid") || lowerQuery.contains("trace-") || 
                lowerQuery.contains("分析") || lowerQuery.contains("解决方案") || lowerQuery.contains("智能")) {
                selectedTools.add("trace_analysis");
            } else {
                selectedTools.add("trace_error_context");
            }
        }
        
        // 专门检测traceId分析请求
        if (lowerQuery.contains("traceid") || 
            (lowerQuery.contains("trace") && (lowerQuery.contains("分析") || lowerQuery.contains("错误") || lowerQuery.contains("解决方案")))) {
            selectedTools.clear(); // 清除其他工具
            selectedTools.add("trace_analysis");
            
            // 尝试提取traceId
            String traceIdPattern = "traceid[=为：]?([\\w-]+)";
            java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(traceIdPattern, java.util.regex.Pattern.CASE_INSENSITIVE);
            java.util.regex.Matcher matcher = pattern.matcher(query);
            if (matcher.find()) {
                parameters.put("traceId", matcher.group(1));
            } else {
                // 尝试从query中提取trace-开头的ID
                pattern = java.util.regex.Pattern.compile("trace[-_]([\\w-]+)", java.util.regex.Pattern.CASE_INSENSITIVE);
                matcher = pattern.matcher(query);
                if (matcher.find()) {
                    parameters.put("traceId", "trace-" + matcher.group(1));
                }
            }
        }
        
        // 如果没有匹配到工具，默认使用搜索
        if (selectedTools.isEmpty() && availableTools.contains("search_logs")) {
            selectedTools.add("search_logs");
        }
        
        // 提取时间范围参数
        if (lowerQuery.contains("最近1小时") || lowerQuery.contains("last_1h")) {
            parameters.put("timeRange", "last_1h");
        } else if (lowerQuery.contains("最近24小时") || lowerQuery.contains("last_24h")) {
            parameters.put("timeRange", "last_24h");
        } else if (lowerQuery.contains("最近7天") || lowerQuery.contains("last_7d")) {
            parameters.put("timeRange", "last_7d");
        }
        
        return new ToolSelectionResult(selectedTools, parameters, 
            "基于关键词规则匹配选择的工具: " + String.join(", ", selectedTools));
    }
    
    /**
     * 基于模板的结果综合（备选方案）
     */
    private AnalysisResponse performTemplateBasedSynthesis(String query, Map<String, Object> toolResults) {
        StringBuilder summary = new StringBuilder("日志分析结果摘要:\n");
        StringBuilder analysis = new StringBuilder("详细分析:\n");
        List<String> recommendations = new ArrayList<>();
        
        for (Map.Entry<String, Object> entry : toolResults.entrySet()) {
            String toolName = entry.getKey();
            Object result = entry.getValue();
            
            summary.append("- ").append(getToolDisplayName(toolName)).append(": 执行完成\n");
            analysis.append("\n").append(getToolDisplayName(toolName)).append("结果:\n");
            analysis.append(formatToolResult(result)).append("\n");
        }
        
        // 添加通用建议
        recommendations.add("建议定期检查错误日志，及时处理异常情况");
        recommendations.add("可使用追踪ID进行更详细的问题定位");
        recommendations.add("建议设置监控告警，主动发现系统问题");
        
        return new AnalysisResponse(summary.toString(), analysis.toString(), recommendations);
    }
    
    private String getToolDisplayName(String toolName) {
        switch (toolName) {
            case "search_logs": return "日志搜索";
            case "analyze_errors": return "错误分析";
            case "get_log_statistics": return "统计分析";
            case "trace_error_context": return "追踪分析";
            default: return toolName;
        }
    }
    
    private String formatToolResult(Object result) {
        try {
            return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(result);
        } catch (Exception e) {
            return result.toString();
        }
    }
    
    private String buildToolSelectionPrompt(String query, List<String> availableTools) {
        return String.format("""
            你是一个日志分析助手，需要根据用户查询选择合适的分析工具。
            
            用户查询: %s
            
            可用工具:
            - search_logs: 搜索和过滤日志
            - analyze_errors: 分析错误和异常
            - get_log_statistics: 统计分析
            - trace_error_context: 追踪分析
            
            请选择1-2个最合适的工具，并提取相关参数。
            返回JSON格式: {"tools": ["tool1", "tool2"], "parameters": {"key": "value"}, "reasoning": "选择理由"}
            """, query);
    }
    
    private String buildSynthesisPrompt(String query, Map<String, Object> toolResults) {
        return String.format("""
            用户查询: %s
            
            工具执行结果: %s
            
            请分析这些结果并提供:
            1. 简要摘要
            2. 详细分析
            3. 建议措施
            
            返回JSON格式: {"summary": "摘要", "analysis": "分析", "recommendations": ["建议1", "建议2"]}
            """, query, formatToolResult(toolResults));
    }
    
    private String callDeepSeekAPI(String prompt) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(apiKey);
        
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", model);
        requestBody.put("temperature", 0.1);
        requestBody.put("messages", Arrays.asList(
            Map.of("role", "user", "content", prompt)
        ));
        
        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
        String response = restTemplate.postForObject(apiUrl, request, String.class);
        
        // 解析响应
        JsonNode jsonNode = objectMapper.readTree(response);
        return jsonNode.path("choices").get(0).path("message").path("content").asText();
    }
    
    private ToolSelectionResult parseToolSelectionResponse(String response, List<String> availableTools) {
        try {
            JsonNode jsonNode = objectMapper.readTree(response);
            
            List<String> tools = new ArrayList<>();
            JsonNode toolsNode = jsonNode.path("tools");
            if (toolsNode.isArray()) {
                for (JsonNode tool : toolsNode) {
                    String toolName = tool.asText();
                    if (availableTools.contains(toolName)) {
                        tools.add(toolName);
                    }
                }
            }
            
            Map<String, Object> parameters = new HashMap<>();
            JsonNode paramsNode = jsonNode.path("parameters");
            if (paramsNode.isObject()) {
                paramsNode.fields().forEachRemaining(entry -> 
                    parameters.put(entry.getKey(), entry.getValue().asText())
                );
            }
            
            String reasoning = jsonNode.path("reasoning").asText("LLM分析结果");
            
            return new ToolSelectionResult(tools, parameters, reasoning);
        } catch (Exception e) {
            logger.warn("解析LLM工具选择响应失败: {}", e.getMessage());
            return performRuleBasedToolSelection("", availableTools);
        }
    }
    
    private AnalysisResponse parseSynthesisResponse(String response) {
        try {
            JsonNode jsonNode = objectMapper.readTree(response);
            
            String summary = jsonNode.path("summary").asText("分析完成");
            String analysis = jsonNode.path("analysis").asText("详细分析结果");
            
            List<String> recommendations = new ArrayList<>();
            JsonNode recsNode = jsonNode.path("recommendations");
            if (recsNode.isArray()) {
                for (JsonNode rec : recsNode) {
                    recommendations.add(rec.asText());
                }
            }
            
            return new AnalysisResponse(summary, analysis, recommendations);
        } catch (Exception e) {
            logger.warn("解析LLM综合响应失败: {}", e.getMessage());
            return new AnalysisResponse("分析完成", "详细分析结果", Arrays.asList("请查看具体的工具执行结果"));
        }
    }
}